
/*
 * if "VoiceRes" partition is placed at flash device that supports mapping-read,
 * use this implement!
 * the eflash supports mapping-read.
 */

#include "voice_common.h"
#include "voice_partition.h"
//#include "amr_test.h"

#if (defined(GKT_CONFIG_VOICE_OUTPUT_ENABLE) && GKT_CONFIG_VOICE_OUTPUT_ENABLE)

uint32_t voice_output_get_all_meta_data(voice_output_s *output)
{
	gkt_voice_meta_id_t meta_id = 0;
	uint32_t data_index = 0;

	output->meta_left_frame_nums = 0;
	for (output->meta_id_index = 0; output->meta_id_index < output->combined_attr->meta_nums; output->meta_id_index++) {
		meta_id = output->combined_attr->meta_ids[output->meta_id_index];
		if (meta_id < output->c_header->meta_nums) {
			memcpy(&output->meta_buffer[data_index], output->c_meta_data_base + output->c_meta_attrs[meta_id].data_offset, output->c_meta_attrs[meta_id].data_size);
			data_index += output->c_meta_attrs[meta_id].data_size;
			if (data_index >= output->meta_buffer_size) {
				gkt_error("voice_output_get_all_meta_data error. meta_buff is too small\n");
				return GKT_ENOMEMORY;
			}
			gkt_trace("map: data_offset=%d, data_index=%d\n", 
					output->c_meta_attrs[meta_id].data_offset, data_index);
		}
	}
	return GKT_SUCCESS;
}

void voice_output_next_meta(voice_output_s *output)
{
	gkt_voice_meta_id_t meta_id = 0;

	output->meta_left_frame_nums = 0;
	output->meta_id_index++;
	while (output->meta_id_index < output->combined_attr->meta_nums) {
		meta_id = output->combined_attr->meta_ids[output->meta_id_index];
		if (meta_id < output->c_header->meta_nums) {
			output->meta_data = output->c_meta_data_base + output->c_meta_attrs[meta_id].data_offset;

#if !GKT_VOICE_DEC_INPUT_FRAME_SIZE
			output->meta_left_frame_nums = output->c_meta_attrs[meta_id].frame_nums;
#else
			output->meta_left_frame_nums = output->c_meta_attrs[meta_id].data_size / GKT_VOICE_DEC_INPUT_FRAME_SIZE;
#endif
			gkt_trace("map: data_offset=%d, meta_left_frame_nums=%d\n", 
					output->c_meta_attrs[meta_id].data_offset, output->meta_left_frame_nums);

			if (output->meta_left_frame_nums)
				break;
		}

		output->meta_id_index++;
	}
	gkt_trace("meta map: id(%d - %d), frame(0x%x - %d)\n", 
			output->meta_id_index, meta_id, (uint32_t)output->meta_data, output->meta_left_frame_nums);
}

void voice_output_sync_resource(voice_output_s *output)
{
	//It is used to switch between Chinese and English voices
	output->c_header = (const voice_output_partition_header_s *)g_voice_partition[GKT_LAGNUAGE];
	output->c_meta_attrs = (const voice_output_meta_attr_s *)(output->c_header + 1);
	output->c_meta_data_base = (const uint8_t *)(output->c_meta_attrs + output->c_header->meta_nums);
}
int voice_output_check_resource(voice_output_s *output)
{
	int retval = GKT_SUCCESS;

	output->c_meta_attrs = NULL;

	output->c_header = (const voice_output_partition_header_s *)g_voice_partition[GKT_LAGNUAGE];
	if ((VOICE_OUTPUT_PART_MAGIC == output->c_header->magic)
		&& (output->c_header->meta_nums <= GKT_VOICE_OUTPUT_META_MAXNUMS)
		&& (output->c_header->meta_data_totalsize <= VOICE_OUTPUT_META_DATA_TOTALSIZE)) 
	{
#if 0
		uint32_t total_size;
		total_size = VOICE_OUTPUT_PARTITION_HEADER_SIZE 
					+ (output->c_header->meta_nums * VOICE_OUTPUT_META_ATTR_SIZE)
					+ output->c_header->meta_data_totalsize;
		if (total_size > sizeof(g_voice_partition[GKT_LAGNUAGE])) {
			gkt_error("voice_output: flash partition space is INSUFFICIENT. total_size=%d\n", total_size);
			return GKT_EUNMATCHED;
		}
#endif
		gkt_trace("voice_output: meta_nums(%u), totalsize(%u)\n",
						output->c_header->meta_nums, 
						output->c_header->meta_data_totalsize);
	}
	else {
		gkt_info("voice_output: voice resource invalid.\n");
		return GKT_EUNMATCHED;
	}

	output->c_meta_attrs = (const voice_output_meta_attr_s *)(output->c_header + 1);
	output->c_meta_data_base = (const uint8_t *)(output->c_meta_attrs + output->c_header->meta_nums);

	return retval;
}

#endif
